package com.csii.servlet;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;


public class UploadHandleServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //设置上传文件的最终保存目录: WEB-INF目录下,不允许外界直接访问,保证上传文件的安全性
        String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
        File file = new File(savePath);
        //判断上传文件的保存目录是否存在
        if (!file.exists() && !file.isDirectory()) {
            System.out.println(savePath + " 目录不存在，需要创建!");
            //创建目录
            file.mkdir();
        }

        String message = "";//提示消息
        InputStream in = null;//输入流
        FileOutputStream out = null;//输出流

        //使用Apache的文件上传组件处理文件上传
        try {
            //1-创建一个DisKFileItemFactory工厂
            DiskFileItemFactory factory = new DiskFileItemFactory();
            //2-创建一个文件上传解析器
            ServletFileUpload servletFileUpload = new ServletFileUpload(factory);
            //解决上传文件名的中文乱码
            servletFileUpload.setHeaderEncoding("UTF-8");
            //3-判断提交上来的数据是否是上传表单的数据
            if (!ServletFileUpload.isMultipartContent(request)) {
                //按照传统方式获取数据
                return;
            }

            //4-使用ServletFileUpload的解析器解析上传的数据,结果是List<FileItem>集合,
            //一个FileItem对应一个Form表单输入项
            List<FileItem> fileItemList = servletFileUpload.parseRequest(request);
            //遍历
            for (FileItem fileItem : fileItemList) {

                if (fileItem.isFormField()) {
                    //fileItem封装的是普通输入项的数据
                    String name = fileItem.getFieldName();
                    //解决普通输入项数据的中文乱码问题
                    String value = fileItem.getString("UTF-8");
                    //value = new String(value.getBytes("iso8859-1"),"UTF-8");
                    System.out.println(name + "  =  " + value);
                } else {
                    //fileItem封装的是上传文件

                    //得到上传文件的名称
                    String fileName = fileItem.getName();
                    System.out.println("上传文件名称fileName  : " + fileName);
                    //
                    if (fileName == null || "".equals(fileName.trim())) {
                        continue;
                    }

                    /**
                     * 不同浏览器提交的文件名是不同的
                     * 某些浏览器提交的文件名中包含路径, eg : c:\a\b\c.txt
                     * 某些浏览器提交的文件名中只有文件名, eg : c.txt
                     */
                    //只保留文件名
                    fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);

                    //获取fileItem中的上传文件的输入流
                    in = fileItem.getInputStream();
                    //创建文件输出流
                    out = new FileOutputStream(savePath + "\\" + fileName);
                    //创建一个缓冲区
                    byte buffer[] = new byte[1024];
                    //判断输入流是否已经读取完毕的标识
                    int length = 0;
                    //循环将输入流读入取到缓冲区中
                    //(length = in.read(buffer)) > 0 表示 输入流中还有数据
                    while ((length = in.read(buffer)) > 0) {
                        //使用FileOutStream输出流将缓冲区的数据写入到指定目录中: savePath+"\\"+fileName
                        out.write(buffer, 0, length);
                    }

                    //删除处理文件上传时生成的临时文件
                    fileItem.delete();
                    //提示信息-成功
                    message = " 文件上传成功 ";

                }

            }

        } catch (Exception e) {
            //提示信息=失败
            message = " 文件上传失败 ";
            e.printStackTrace();
        } finally {
            //关闭输入流
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            //关闭输出流
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        request.setAttribute("message", message);
        request.getRequestDispatcher("/message.jsp").forward(request, response);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}
